package com.bookmall.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bookmall.common.constant.CategoryLevelConstant;
import com.bookmall.common.constant.MyStatusConstants;
import com.bookmall.common.utils.MyQuery;
import com.bookmall.common.utils.PageUtils;
import com.bookmall.product.domain.BookCategory;
import com.bookmall.product.mapper.BookCategoryMapper;
import com.bookmall.product.service.IBookCategoryService;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description:
 * @Author 胡菜鸡
 * @Create 2022-02-21-17:00
 */
@Service("bookCategoryService")
public class BookCategoryServiceImpl extends ServiceImpl<BookCategoryMapper, BookCategory> implements IBookCategoryService {

    @Resource
    private BookCategoryMapper bookCategoryMapper;

    /**
     * 根据实体类分页查询分类列表
     * @author 胡菜鸡
     * @date 2022/2/21 18:30
     */
    @Override
    public PageUtils selectCategoryList(BookCategory bookCategory) {
        LambdaQueryWrapper<BookCategory> wrapper = new LambdaQueryWrapper<>(bookCategory);

        IPage<BookCategory> page = this.page(new MyQuery<BookCategory>().getPage(bookCategory), wrapper);
        return new PageUtils(page);
    }

    /**
     * 获取所有分类（以树形列表返回）
     * @author 胡菜鸡
     * @date 2022/2/21 22:29
     */
    @Override
    public List<BookCategory> listWithTree(BookCategory bookCategory) {
        LambdaQueryWrapper<BookCategory> wrapper = new LambdaQueryWrapper<>();
        String level = "0";
        if(bookCategory.getCatLevel() != null){
            level = bookCategory.getCatLevel() + "";
            wrapper.eq(BookCategory::getCatLevel, bookCategory.getCatLevel());
        }
        if(!StringUtils.isBlank(bookCategory.getCatName())){
            wrapper.like(BookCategory::getCatName, bookCategory.getCatName());
        }
        //1.查出所有分类
        List<BookCategory> categories = this.baseMapper.selectList(wrapper);
        if(!StringUtils.isBlank(bookCategory.getCatName()) || bookCategory.getCatLevel() != null){
            return categories;
        }
        //2.组装成父子的树形结构
        List<BookCategory> treeMenus = getTreeList(level, categories);
        if(treeMenus == null){
            return new ArrayList<>();
        }
        return treeMenus;
    }

    /**
     * 获取所有展示的分类（以树形列表返回）
     * @author 胡菜鸡
     * @date 2022/2/22 17:12
     */
    @Override
    public List<BookCategory> listWithTreeForStatus() {
        //1.查出所有正常状态的分类
        LambdaQueryWrapper<BookCategory> wrapper = new LambdaQueryWrapper<>();
        List<BookCategory> categories = this.baseMapper.selectList(wrapper.eq(BookCategory::getStatus, MyStatusConstants.NORMAL));
        //2.组装成父子的树形结构
        List<BookCategory> treeMenus = getTreeList("0", categories);
        return treeMenus;
    }

    /**
     * 获取分类下的所有子分类
     * @author 胡菜鸡
     * @date 2022/3/12 16:35
     */
    @Override
    public List<BookCategory> getChildrenCategory(String categoryId) {
        //1.查出所有正常状态的分类
        LambdaQueryWrapper<BookCategory> wrapper = new LambdaQueryWrapper<>();
        List<BookCategory> categories = bookCategoryMapper.selectList(wrapper.eq(BookCategory::getStatus, MyStatusConstants.NORMAL));
        //2.从所有分类中找出id对应的所有子分类（包括子分类的子分类）
        List<BookCategory> childrenList = getChildrenList(categoryId, categories, new ArrayList<>());
        return childrenList;
    }

    /**
     * 找出所有直接
     * @author 胡菜鸡
     * @date 2022/3/12 16:49
     * @param parentId 需要寻找子分类的id
     * @param all 寻找的全部分类集合
     * @param result 所有查询到的子分类都会添加到此集合中
     * @return 返回参数 result 和子分类集合合并的结果集合
     */
    private List<BookCategory> getChildrenList(String parentId, List<BookCategory> all, List<BookCategory> result){
        //1.找出直属子分类
        List<BookCategory> collect = all.stream().filter(categoryEntity -> {
            return parentId.equals(categoryEntity.getParentCid());
        }).collect(Collectors.toList());
        if(collect == null || collect.size() == 0) return null;

        result.addAll(collect);

        //2.寻找直属子分类的子分类
        collect.stream().forEach(categoryEntity -> {
            getChildrenList(categoryEntity.getId(), all, result);
        });
        return result;
    }

    /**
     * 将List列表改造为树型列表
     *
     * @author 胡菜鸡
     * @date 2021/12/14 17:33
     */
    private List<BookCategory> getTreeList(String parentId, List<BookCategory> all) {
        List<BookCategory> children = all.stream().filter(categoryEntity -> {
            //过滤集合找到父ID正确的内容（这里因为是Long型值所以不能用 == 比较）
            return parentId.equals(categoryEntity.getParentCid());
        }).map(categoryEntity -> {
            //获取子集合的子集
            categoryEntity.setChildren(getTreeList(categoryEntity.getId(), all));
            return categoryEntity;
        }).sorted((menu1, menu2) -> {
            //按照数据库标识的字段进行排序
            return menu1.getSort() - menu2.getSort();
        }).collect(Collectors.toList());
        if(children != null && children.size() == 0){
            return null;
        }
        return children;
    }



    /**
     * 根据id删除分类
     * @author 胡菜鸡
     * @date 2022/2/22 16:02
     */
    @Override
    public int removeCategoryByIds(List<String> ids) {
        if(ids.contains("0")){
            throw new ServiceException("存在无法删除的分类，您需要删除的分类中可能包含 '无' 选项");
        }
        for (String id : ids) {
            if(hasChildrenCategory(id)){
                throw new ServiceException("部分分类存在子分类，无法进行删除操作");
            }
        }
        return this.baseMapper.deleteBatchIds(ids);
    }

    /**
     * 检查当前分类是否存在子分类
     * @author 胡菜鸡
     * @date 2022/2/22 16:02
     */
    @Override
    public boolean hasChildrenCategory(String id) {
        LambdaQueryWrapper<BookCategory> wrapper = new LambdaQueryWrapper<>();
        Long count = this.baseMapper.selectCount(wrapper.eq(BookCategory::getParentCid, id));
        return count > 0;
    }

    /**
     * 新增分类
     * @author 胡菜鸡
     * @date 2022/2/22 16:46
     */
    @Override
    public int insertCategory(BookCategory bookCategory) {
        if(bookCategory.getParentCid() != null && !"0".equals(bookCategory.getParentCid())){
            // 新增分类的父分类
            BookCategory parentCategory = this.baseMapper.selectById(bookCategory.getParentCid());
            // 新增分类层级为父分类层级+1
            bookCategory.setCatLevel(parentCategory.getCatLevel()+1);
        } else {
            bookCategory.setCatLevel(1);
        }
        return this.baseMapper.insert(bookCategory);
    }

    /**
     * 根据id修改分类
     * @author 胡菜鸡
     * @date 2022/2/22 17:17
     */
    @Override
    public int updateCategoryById(BookCategory bookCategory) {
        // 根据id查找出原来未修改的数据
        BookCategory pastCategory = this.baseMapper.selectById(bookCategory.getId());
        
        // 查找修改分类的子分类
        LambdaQueryWrapper<BookCategory> wrapper = new LambdaQueryWrapper<>();
        Long count = baseMapper.selectCount(wrapper.eq(BookCategory::getParentCid, bookCategory.getId()));

        // 如果当前修改的分类有子分类，则不准其修改父分类
        boolean sameParent = bookCategory.getParentCid().equals(pastCategory.getParentCid());   //修改分类和原来分类的父分类是否相同
        if(count > 0 && !sameParent){
            throw new ServiceException("当前分类存在子节点，无法修改其父分类");
        }

        // 允许修改父分类：没有子分类
        if(count == 0 && !sameParent){
            if("0".equals(bookCategory.getParentCid())){
                bookCategory.setCatLevel(1);
            } else {
                // 新增分类的父分类
                BookCategory parentCategory = baseMapper.selectById(bookCategory.getParentCid());
                // 修改分类层级为父分类层级+1
                bookCategory.setCatLevel(parentCategory.getCatLevel()+1);
            }
        }
        return baseMapper.updateById(bookCategory);
    }

    /**
     * 查询书籍的一级分类
     * @author 胡菜鸡
     * @date 2022/3/17 17:54
     * @param
     * @return
     */
    @Override
    public List<BookCategory> getLevel1Categorys() {
        LambdaQueryWrapper<BookCategory> wrapper = new LambdaQueryWrapper<>();
        List<BookCategory> categoryList = bookCategoryMapper.selectList(wrapper.eq(BookCategory::getCatLevel, CategoryLevelConstant.FIRST));
        return categoryList;
    }
}
